package com.ruoyi.framework.security.filter.ykb;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.digital.szzz.gateway.sdk.api.GatewaySender;
import com.digital.szzz.gateway.sdk.bean.GatewayResponse;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.filter.ykz.CustomUserDetails;
import com.ruoyi.framework.security.filter.ykz.IntelligentPostService;
import com.ruoyi.framework.security.filter.ykz.OapiRpcAuth2UserInfo;
import com.ruoyi.framework.security.filter.ykz.YKZAuthenticationToken;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 处理渝快办系统的登录认证逻辑，包括从外部服务获取用户信息、加载用户详细信息、创建认证成功的 Authentication 对象等功能
 */
@Slf4j
@Component
public class YKBAuthenticationProvider implements AuthenticationProvider {

	@Value("${ykb.auth.url}")
	private String url;
	@Value("${ykb.auth.appKey}")
	private String appKey;
	@Value("${ykb.auth.appIv}")
	private String appIv;
	@Value("${ykb.auth.appId}")
	private String appId;
	@Value("${ykb.auth.appSecret}")
	private String appSecret;

	@Autowired
	private SysUserMapper userMapper;
	
	private final static GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
	
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		log.info("authentication:{}", authentication);
		YKZAuthenticationToken token = (YKZAuthenticationToken) authentication;
		log.info("渝快办token:{}", token);
		// 渝快办登录请求带过来的code
		String authCode = token.getCode();
		YkbUserInfo ykbUserInfo = this.getYkbUserInfo(authCode);
		log.info("渝快办用户YKBUser:{}", ykbUserInfo);
		if (Objects.isNull(ykbUserInfo)) {
			throw new RuntimeException(authCode + ", 用户不存在");
		}
		String ykbUserId = ykbUserInfo.getId();
		// 根据userid获取系统用户
		SysUser user = null;
		user = userMapper.selectUserByAccountId(String.valueOf(ykbUserId));
		if (Objects.isNull(user) && StringUtils.isNotBlank(ykbUserInfo.getPhone())) {
			user = userMapper.selectUserByPhone(ykbUserInfo.getPhone());
			user.setAccountId(ykbUserId);
			userMapper.updateUser(user);
			log.info("更新SysUser成功:{}", user);
		}

		log.info("系统用户SysUser:{}", user);
		if (Objects.isNull(user)) {
			// 系统用户不存在 插入用户
			user = new SysUser();
			user.setAccountId(String.valueOf(ykbUserId));
			user.setUserName(ykbUserInfo.getUserName());
			user.setNickName(ykbUserInfo.getUserName());
			user.setUserType("11");
			user.setPhonenumber(ykbUserInfo.getPhone());
			int i = userMapper.insertUser(user);
			log.info("插入SysUser成功:{}", user);
		}
		token.setCredentials(user);
		CustomUserDetails userDetails = new CustomUserDetails(user);
		return createSuccessAuthentication(user, authentication, userDetails);
	}

	/**
	 * 获取渝快办用户
	 * @param authCode
	 * @return
	 */
	private YkbUserInfo getYkbUserInfo(String authCode) {
		String url = this.url; //请求地址
		String appId = this.appId;// 应用唯一标识
		String appIv= this.appIv; // app加密偏移量
		String appKey = this.appKey;//app加密key
		String appSecretKey = this.appSecret;//app加密秘钥
//		String authCode = authCode; //用户授权令牌
		Integer readTimeout = 1000;//接口读取超时时间 ms
		Integer connTimeout = 1000;//接口连接超时时间 ms
		String method = "app.ykb.uc.oauth.userInfo";
		JSONObject parame = new JSONObject();
		parame.put("authCode", authCode);
		Map<String, String> headerMap = new HashMap<>();
		GatewayResponse response = GatewaySender.send(url, appId, method, appIv, appKey, appSecretKey, parame, authCode, headerMap, readTimeout, connTimeout);
		log.info("渝快办用户信息响应参数:{}", response);
		if (response.getCode()!=0) {
			throw new RuntimeException(response + ", 获取用户失败");
		}
		String dataStr = response.getData();
//		String data = JSON.parseObject(dataStr).getJSONObject("content").getString("data");
		YkbUserInfo userInfo = JSON.parseObject(dataStr, YkbUserInfo.class);
		log.info("处理后渝快办YkbUserInfo:{}", userInfo);
		return userInfo;
	}


	protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
		YKZAuthenticationToken result = new YKZAuthenticationToken(principal, authentication.getCredentials(), authoritiesMapper.mapAuthorities(user.getAuthorities()));
        result.setDetails(authentication.getDetails());
        return result;
    }
	
	@Override
	public boolean supports(Class<?> authentication) {
		return YKZAuthenticationToken.class.isAssignableFrom(authentication);
	}

}
